package Pointers;

import interfaces.Pointer;
import Script.Offset;

public class SnesPointer implements Pointer {
	private long position;	// Position along other pointers
	private Offset offset;		// Offset this pointer is pointing at
	private Offset fileOffset; // Offset in the file
	
	/**
	 * @param off This offset must be in the format used when
	 * 			  reading from a snes rom, i.e little endian.
	 */
	public SnesPointer(int position, Offset off, Offset fileOffset) {
		this.position = position;
		this.fileOffset = fileOffset;
		offset = new Offset(off.getLongValue(2));
		
		offset.switchEndian();
		offset.setEndian(false);
		
		long val = offset.getLongValue(2);
		offset = new Offset(val);
		offset.setEndian(true);
	}
	
	@Override
	/**
	 * Returns the lowest 2 bytes of the pointer offset.
	 */
	public Long getValue() {
		long ret;
		
		if (!offset.getEndian()) {
			offset.switchEndian();
			ret = offset.getValue();
			offset.switchEndian();
		} else {
			ret = offset.getValue();
		}
		return ret;
	}
	
	@Override
	public byte[] printValue() {
		byte[] data;
		
		if (offset.getEndian()) {
			offset.switchEndian(); // To little endian
			data = offset.getByteValue(2);
			offset.switchEndian(); // Back to big endian
			
		} else {
			data = offset.getByteValue(2);
		}

		return data;
	}
	
	@Override
	public void setValue(Offset newOffset) {
		this.offset = new Offset(newOffset.getLongValue(2));
	}
	
	@Override
	public String hexValue() {
		return offset.getHex(2);
	}
	
	@Override
	public Long getPosition() {
		return position;
	}
	
	@Override
	public Offset getFileOffset() {
		return fileOffset;
	}

	@Override
	public int compareTo(Pointer p) {
		if (this.getValue() > p.getValue()) {
			return 1;
		} else if (this.getValue() == p.getValue()) {
			return 0;
		} else {
			return -1;
		}
	}

	
}
